<?php

namespace service\impl;

use service\exception\ServiceException;
use service\ext\PageData;
use service\service\UserVipOrderService;
use service\vo\user\UserVipOrder;
use think\db\exception\DbException;

class UserVipOrderServiceImpl extends BaseImpl implements UserVipOrderService
{
    private static string $modeName = 'userVipOrder';

    /**
     * @inheritDoc
     */
    public function addUserVipOrder(UserVipOrder $userVipOrder): int
    {
        // TODO: Implement addUserVipOrder() method.
        $data = [
            self::$FIELD_VIP_ORDER_ADD_TIME => date("Y-m-d H:i:s"),
            self::$FIELD_VIP_ORDER_MONEY => $userVipOrder->getOrderMoney(),
            self::$FIELD_VIP_ORDER_INNER_NUM => date("YmdHis") . mt_rand(100000, 999999),
            self::$FIELD_COMMON_U_ID => $userVipOrder->getUserId(),
            self::$FIELD_VIP_ORDER_PAY_TYPE => $userVipOrder->getPayType(),
            self::$FIELD_VIP_ORDER_PAY_MONEY => $userVipOrder->getPayMoney(),
            self::$FIELD_VIP_ORDER_EXPIRE_TIME => $userVipOrder->getExpireTime()
        ];
        return $this->getVipOrderDb()->insertGetId($data);
    }

    /**
     * @inheritDoc
     */
    public function payUserVipOrder(string $innerNum, string $outNum, int $orderMoney, int $payMoney): int
    {
        // TODO: Implement payUserVipOrder() method.
        //查询订单号是否存在
        $po = $this->getVipOrderDb()
            ->where(self::$FIELD_VIP_ORDER_INNER_NUM, $innerNum)
            ->find();
        if(empty($po)){
            throw new ServiceException(self::$modeName, self::ERROR_CHARGE_INNER_NUM_NOT_EXISTS);
        }
        if($po[self::$FIELD_VIP_ORDER_PAY_STATUS] == 1){
            throw new ServiceException(self::$modeName, self::ERROR_CHARGE_INNER_NUM_PAYED);
        }
        if($po[self::$FIELD_VIP_ORDER_MONEY] != $orderMoney){
            throw new ServiceException(self::$modeName, self::ERROR_CHARGE_MONEY_ERROR);
        }
        if($po[self::$FIELD_VIP_ORDER_PAY_MONEY] != $payMoney){
            throw new ServiceException(self::$modeName, self::ERROR_CHARGE_PAY_MONEY_ERROR);
        }
        //判断订单是否过期
        $thisDate = time();
        if($thisDate > $po[self::$FIELD_VIP_ORDER_EXPIRE_TIME]){
            throw new ServiceException(self::$modeName, self::ERROR_CHARGE_EXPIRE_TIME);
        }

        //更新订单信息
        $data = [
            self::$FIELD_VIP_ORDER_PAY_STATUS => 1,
            self::$FIELD_VIP_ORDER_OUT_NUM => $outNum,
            self::$FIELD_VIP_ORDER_PAY_TIME => date("Y-m-d H:i:s")
        ];

        return $this->getVipOrderDb()->where(self::$FIELD_VIP_ORDER_INNER_NUM, $innerNum)->update($data);
    }

    /**
     * @inheritDoc
     * @throws DbException
     */
    public function deleteUserVipOrderById(int $id): int
    {
        // TODO: Implement deleteUserVipOrderById() method.
        return $this->getVipOrderDb()->where(self::$FIELD_COMMON_ID, $id)->delete();
    }

    /**
     * @inheritDoc
     * @throws DbException
     */
    public function deleteUserVipOrderByIds(array $ids): int
    {
        // TODO: Implement deleteUserVipOrderByIds() method.
        return $this->getVipOrderDb()->whereIn(self::$FIELD_COMMON_ID, $ids)->delete();
    }

    /**
     * @inheritDoc
     * @throws DbException
     * @throws ServiceException
     */
    public function getUserVipOrderByInnerNum(int $innerNum): UserVipOrder
    {
        // TODO: Implement getUserVipOrderByInnerNum() method.
        $po = $this->getVipOrderDb()
            ->where(self::$FIELD_VIP_ORDER_INNER_NUM, $innerNum)
            ->find();
        if(empty($po)){
            throw new ServiceException(self::$modeName, self::ERROR_DATA_NOT_EXISTS);
        }

        return $this->getVipOrderVoFromPo($po);
    }

    /**
     * @inheritDoc
     * @throws DbException
     * @throws ServiceException
     */
    public function getUserVipOrderById(int $id): UserVipOrder
    {
        // TODO: Implement getUserVipOrderById() method.
        $po = $this->getVipOrderDb()
            ->where(self::$FIELD_COMMON_ID, $id)
            ->find();
        if(empty($po)){
            throw new ServiceException(self::$modeName, self::ERROR_DATA_NOT_EXISTS);
        }
        return $this->getVipOrderVoFromPo($po);
    }

    /**
     * @inheritDoc
     * @throws DbException
     */
    public function searchUserVipOrder(int $currentPage, int $pageSize, array $filterCriteria, array $sorterCriteria): PageData
    {
        // TODO: Implement searchUserVipOrder() method.
        $filter = [];
        if (!empty($filterCriteria)) {
            foreach ($filterCriteria as $key => $value) {
                if (strcasecmp($key, self::$FILTER_INNER_NUM) == 0) {
                    //内部订单号，模糊查询
                    $filter[] = [self::$FIELD_VIP_ORDER_INNER_NUM, "like", "%{$value}%"];
                } else if (strcasecmp($key, self::$FILTER_OUT_NUM) == 0) {
                    //外部订单号
                    $filter[] = [self::$FIELD_VIP_ORDER_OUT_NUM, "like", "%{$value}%"];
                } else if (strcasecmp($key, self::$FILTER_USER_ID) == 0) {
                    //会员ID
                    $filter[] = [self::$FIELD_COMMON_U_ID, "=", $value];
                } else if (strcasecmp($key, self::$FILTER_STATUS) == 0) {
                    //状态
                    $filter[] = [self::$FIELD_VIP_ORDER_PAY_STATUS, "=", $value];
                } else if (strcasecmp($key, self::$FILTER_PAY_TYPE) == 0) {
                    //支付方式
                    $filter[] = [self::$FIELD_VIP_ORDER_PAY_TYPE, "=", $value];
                } elseif (strcasecmp($key, self::$FILTER_ADD_TIME) == 0) {
                    //时间
                    $betweenTime = makeBetween($value['start'], $value['end']);
                    $filter[] = [self::$FIELD_VIP_ORDER_ADD_TIME, $betweenTime[0], $betweenTime[1]];
                } elseif (strcasecmp($key, self::$FILTER_PAY_TIME) == 0) {
                    //时间
                    $betweenTime = makeBetween($value['start'], $value['end']);
                    $filter[] = [self::$FIELD_VIP_ORDER_PAY_TIME, $betweenTime[0], $betweenTime[1]];
                }
            }
        }

        //构建排序条件
        $sort = [];
        if (!empty($sorterCriteria)) {
            foreach ($sorterCriteria as $key => $value) {
                if (strcasecmp($key, self::$SORT_ID) == 0) {
                    $sort[self::$FIELD_COMMON_ID] = $value ? self::$SORT_VALUE_ASC : self::$SORT_VALUE_DESC;
                } else if (strcasecmp($key, self::$SORT_PAY_TIME) == 0) {
                    $sort[self::$FIELD_VIP_ORDER_PAY_TIME] = $value ? self::$SORT_VALUE_ASC : self::$SORT_VALUE_DESC;
                }
            }
        }

        $count = $this->getVipOrderDb()
            ->where($filter)
            ->count();
        $list = $this->getVipOrderDb()
            ->where($filter)
            ->order($sort)
            ->limit($pageSize)
            ->page($currentPage)
            ->select();


        $dataList = [];
        foreach ($list as $po) {
            $dataList[] = $this->getVipOrderVoFromPo($po);
        }

        $pageData = new PageData();
        $pageData->setData($dataList);
        $pageData->setCount($count);

        return $pageData;
    }

    private function getVipOrderVoFromPo($po): UserVipOrder
    {
        $vo = new UserVipOrder();
        $vo->setId($po[self::$FIELD_COMMON_ID]);
        $vo->setUserId($po[self::$FIELD_COMMON_U_ID]);
        $vo->setAddTime($po[self::$FIELD_VIP_ORDER_ADD_TIME]);
        $vo->setPayType($po[self::$FIELD_VIP_ORDER_PAY_TYPE]);
        $vo->setPayMoney($po[self::$FIELD_VIP_ORDER_PAY_MONEY]);
        $vo->setPayTime($po[self::$FIELD_VIP_ORDER_PAY_TIME]);
        $vo->setExpireTime($po[self::$FIELD_VIP_ORDER_EXPIRE_TIME]);
        $vo->setOrderMoney($po[self::$FIELD_VIP_ORDER_MONEY]);
        $vo->setOutNum($po[self::$FIELD_VIP_ORDER_OUT_NUM]);
        $vo->setInnerNum($po[self::$FIELD_VIP_ORDER_INNER_NUM]);
        $vo->setPayStatus($po[self::$FIELD_VIP_ORDER_PAY_STATUS]);
        return $vo;
    }
}